/* 
 *  Copyright (C) 2006 James Young
 * `gurumind(a)gmail.com
 * 
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace IPDEditor
{
    class IPDFieldSBAppDataForBrowser : IPDFieldSBAppData
    {
        public string homeAddress;
        public string dataSource;
        public string dsUID;
        public string name;

        private int[] unknowns;
        Queue<byte> strTag;
        byte[] strTagBuff;
        int strTagBuffIndex;
        private byte[] magicBuff;
        private int maxInt;

        public IPDFieldSBAppDataForBrowser(IPDDatabase db)
            : base(db)
        {
            strTag = new Queue<byte>();
        }

        /// <summary>
        /// appData has no leading type byte.
        /// </summary>
        /// <param name="appData"></param>
        public void Parse(byte [] appData)
        {
            unknowns = new int[25];
            MemoryStream ms = new MemoryStream(appData);
            BinaryReader br = new BinaryReader(ms);
            //byte type = br.ReadByte();
            homeAddress = ReadString(br);
            unknowns[0] = br.ReadInt32();
            dataSource = ReadString(br);
            dsUID = ReadString(br);
            unknowns[1] = br.ReadInt32();
            unknowns[2] = br.ReadInt32();
            unknowns[3] = br.ReadInt32();
            magicBuff = br.ReadBytes(3);
            unknowns[4] = br.ReadInt32();
            unknowns[5] = br.ReadInt32();
            name = ReadString(br);
            maxInt = 25;
            for (int i = 6; i < 25; i++)
            {
                if (br.BaseStream.Position < br.BaseStream.Length)
                {
                    Console.WriteLine(string.Format("pos: {0} len: {1}", br.BaseStream.Position, br.BaseStream.Length));
                    unknowns[i] = br.ReadInt32();
                }
                else
                {
                    maxInt = i;
                    break;
                }
            }
            br.Close();
            ms.Close();
        }

        public void Store(BinaryWriter w)
        {
            strTagBuff = new byte[strTag.Count];
            strTag.CopyTo(strTagBuff, 0);
            strTagBuffIndex = 0;
            WriteString(w, homeAddress);
            w.Write(unknowns[0]);
            WriteString(w, dataSource);
            WriteString(w, dsUID);
            w.Write(unknowns[1]);
            w.Write(unknowns[2]);
            w.Write(unknowns[3]);
            w.Write(magicBuff);
            w.Write(unknowns[4]);
            w.Write(unknowns[5]);
            WriteString(w, name);
            for (int i = 6; i < maxInt; i++)
                w.Write(unknowns[i]);
        }

        public override short Length
        {
            get
            {
                return (short)(homeAddress.Length + dataSource.Length + dsUID.Length + name.Length + 4 * 4 + 3 + maxInt * 4);
            }
        }

        protected string ReadString(BinaryReader r)
        {
            byte z = r.ReadByte();
            byte len = r.ReadByte();
            byte tag = r.ReadByte();
            strTag.Enqueue(tag);
            byte[] buff = r.ReadBytes(len);
            string s = Encoding.ASCII.GetString(buff);
            return s;
        }

        protected void WriteString(BinaryWriter w, string s)
        {
            byte[] buff = new byte[s.Length + 1];
            byte [] tmp = Encoding.ASCII.GetBytes(s);
            for(int i = 0; i < tmp.Length; i++)
                buff[i] = tmp[i];
            buff[s.Length] = 0;

            w.Write((byte)0);
            w.Write((byte)(buff.Length));
            w.Write(strTagBuff[strTagBuffIndex++]);
            w.Write(buff);
        }

    }
}
